package ucd.csi.comp30220.fall2011.oteop.airport;

import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.TreeSet;

/**
 * Represents airport runway.
 * 
 * @author Lukasz Jasinski
 */

public class Runway {
	
	// time needed to free runway after landing (in minutes)
	private final int landingTime = 15;
	// time needed to free runway after departure (in minutes)
	private final int departureTime = 15;
	// minimum time to prepare runway for departure/landing (in minutes)
	private final int minimumTime = 15;
	
	TreeSet<RunwayReservation> flights = new TreeSet<RunwayReservation>(); // comparator is not yet created for this
	
	
	public void addReservation(RunwayReservation reservation){
		
	}
	
	private int getTypeTime(int type){
		switch (type) {
     		case 1: return landingTime;
     		case 2: return departureTime;	
		}
		return 0;
	}
	
	private int minutesBetween(Date d1, Date d2){
		return (int)( (d2.getTime() - d1.getTime()) / (1000 * 60));
	}
	
	private Date addMinutestoDate(Date date, int minutes){
		long sum = date.getTime() + minutes * 60 * 1000;
		return new Date(sum);
	}
	
	public Date checkNearestPossible(int type, Date date){
		
		Date currentClosestDate = new Date();
			
		if(flights.isEmpty()){
			currentClosestDate = date;
		}
		else {
			RunwayReservation previouse = null;
			RunwayReservation current = null;
			Calendar calendar = Calendar.getInstance();
			calendar.add(Calendar.MINUTE, minimumTime);
			
			int timeNeeded = 0;
			
			timeNeeded = getTypeTime(type);		
			
			boolean flag = true;
			Iterator<RunwayReservation> iter = flights.iterator();
			
			Date temp_left;
			Date temp_right;
			
			// hope it works :D
			while(flag){
					if(current == null){
						current = iter.next();
						if(minutesBetween(current.getDate(), calendar.getTime())>=timeNeeded){
							if(minutesBetween(date, current.getDate())>=timeNeeded) currentClosestDate = date;
							else currentClosestDate = addMinutestoDate(current.getDate(), -timeNeeded);
						}
					}
					else if(iter.hasNext()){
						previouse = current;
						current = iter.next();
						if(minutesBetween(current.getDate(), addMinutestoDate(previouse.getDate(), getTypeTime(previouse.getType())))>=timeNeeded){
							temp_right = addMinutestoDate(current.getDate(),-timeNeeded);
							temp_left = addMinutestoDate(previouse.getDate(), getTypeTime(previouse.getType()));
							Date newCurrentClosestDate;
							if(minutesBetween(temp_right,date)<=minutesBetween(temp_left,date))
								newCurrentClosestDate = temp_right;
							else newCurrentClosestDate = temp_left;
							
							if (minutesBetween(newCurrentClosestDate,date)<minutesBetween(currentClosestDate,date))
								currentClosestDate = newCurrentClosestDate;
							else break;
						}
					}
					else{
						temp_left = addMinutestoDate(current.getDate(), getTypeTime(current.getType()));
						if(temp_left.compareTo(date)<=0){
							currentClosestDate = date;
							break;
						}
					}
			}
		}
		
		return currentClosestDate;
	}
}
